/**
 * 
 * @Copyright (c) 2015 Messcat. All rights reserved.
 */
package cc.messcat.service.system;

import cc.messcat.common.model.JDBCSettingBean;
import cc.messcat.common.util.DataHandler;
import cc.messcat.dao.system.SystemDao;
import cc.messcat.service.log.LogService;
import cc.messcat.util.Collections;
import cc.messcat.util.IPUtil;
import org.apache.commons.io.input.ReversedLinesFileReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

/**
 * @author Panda
 * @version 1.0
 */
@Service
public class SystemServiceImpl implements SystemService {
	private Logger logger = LoggerFactory.getLogger("数据备份");

	@Autowired
	private JDBCSettingBean jdbcSettingBean;

	@Autowired
	private SystemDao systemDao;
	
	@Autowired
	private LogService logService;
	
	private String historyFilename =  "backup.history";
	/*
	 * (non-Javadoc)
	 * @see cc.messcat.service.system.SystemService#backupData()
	 */
	@Override
	public File backupData() throws Exception {
		String targetFilePath = DataHandler.backupDatabaseScript(jdbcSettingBean);
		return new File(targetFilePath);
	}

	/**
	 * 年度数据备份
	 * @throws Exception 
	 */
	@Override
	public Map<String,Object> annualBackup(Integer origin, Integer derivation,HttpSession session,HttpServletRequest request) throws Exception {
		return systemDao.annualBackup(origin,derivation,session,IPUtil.getIpAddr(request));
	}
	
	/**
	 * 备份失败时的数据恢复(windows)
	 * 如果没有按年份选定文件则默认执行上次备份的文件
	 * @param origin
	 * @param derivation
	 */
	@Override
	public Map<String,String> restore(Integer origin ,Integer derivation) {
		Map<String,String> result = new HashMap<>();
		Map<String, String> msg = new HashMap<>();
		String filePath = "";
		String startTimeMarker = "";
		if(origin != null && origin > 0 && derivation != null && derivation > 0) {
//			 filePath = jdbcSettingBean.getDataPath() +"\\"+ origin.toString() + "_" + derivation.toString() + ".backup";
		} else {
			 try {
				List<Map<String, String>> backupInfo = systemDao.getBackupInfo();
                 if(Collections.isEmpty(backupInfo)) {
                     result.put("msg", "没有找到相关文件");
                     return result;
                 }
				Map<String, String> record = backupInfo.get(backupInfo.size()-1);
				
//				String[] originAndDerivation = record.get("backup_filename").split("-");
				filePath = jdbcSettingBean.getDataPath() +"\\"+ record.get("backup_filename") + ".backup";
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		File backupFilePath = new File(filePath);
		if(!backupFilePath.exists()) {
			result.put("msg", "没有找到恢复文件");
			return result;
		}
		StringBuffer cmd = new StringBuffer("cmd.exe /c cmd /c ");
		cmd.append("\""+jdbcSettingBean.getMysqldump().split("bin")[0] +"bin\\mysql.exe\"");	// 	
		cmd.append(" -h");						//	-h
		cmd.append(jdbcSettingBean.getHost());			
		cmd.append(" -u");						//	-u
		cmd.append(jdbcSettingBean.getUserName());		
		cmd.append(" -p");						//	-p
		cmd.append(jdbcSettingBean.getPassword());		
		cmd.append(" ");						//	 
		cmd.append(jdbcSettingBean.getDatabaseName());	
		cmd.append(" < \"" + filePath+"\"");
		System.out.println(cmd.toString());
		int state = 12;
		try {
			Process exec = Runtime.getRuntime().exec(cmd.toString());
			state = exec.waitFor();
			if(0!=state) throw new RuntimeException("命令执行出错：状态为"+state);

			//处理历史记录文件
			updateBackupHistoryFile();
			//删除文件
			new File(filePath).delete();

			result.put("msg","恢复成功");
		} catch (Exception e) {
			logger.error("状态:"+state + "\r\n操作命令："+cmd.toString() + " \r\n " + e.getMessage());
			result.put("msg","恢复失败, 状态:"+state);

		}
		return result;
	}

	@Override
	public List<Map<String, String>> getBackupInfo() {
		try {
			return systemDao.getBackupInfo();
		} catch (IOException e) {
			e.printStackTrace();
			return Collections.generateArrayList(Collections.<String, String>generateHashMap("msg", "没有找到相关文件"));
		}
	}

	/**
	 * 回退后删除最新的记录
	 */
	private Map<String, String> updateBackupHistoryFile() {
		Map<String, String> result = new HashMap<>();
		File backupFilePath = new File(jdbcSettingBean.getDataPath());
		File historyFile = new File(backupFilePath + "/" + historyFilename);
		int n_lines = 1;
		int counter = 1;
		String line = null;
		int i = 0;
		try {
			ArrayList<String> array = new ArrayList<String>();
			ReversedLinesFileReader object = new ReversedLinesFileReader(historyFile, 4096,"UTF-8");
			while ((line = object.readLine()) != null) {
				if (counter == n_lines) {
					if (line.startsWith("*")) {
						i++;
					}
					if (i == 1) continue;
//					System.out.println(line);
					array.add(line);
				}
				counter++;
				n_lines++;
			}
			FileWriter out = new FileWriter(historyFile);
			ListIterator<String> iterator = array.listIterator(array.size());
			while (iterator.hasPrevious()) {
				out.write(iterator.previous());
				out.write("\r\n");
			}
			out.close();
			result.put("msg", "删除成功");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.put("msg", "删除失败");
		}
		return result;
	}

	/**
	 * 备份情况获取，用于判断是否已备份
	 */
	@Override
	public boolean isBackup(Integer origin ,Integer derivation) {
		List<Map<String, String>> recordList = null;
		try {
			recordList = systemDao.getBackupInfo();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		String lastBackupTime = "";
		for (Map<String, String> map : recordList) {
			String[] ss = map.get("backup").split("-");

			if(ss != null && ss.length > 1 && ss[1].equals(derivation.toString())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取业务年度
	 */
	@Override
	public String getBusinessAnnual() {
		List<Map<String, String>> recordList = null;
		try {
			recordList = systemDao.getBackupInfo();
		} catch (IOException e) {
			e.printStackTrace();
		}

		TreeSet<Integer> set = new TreeSet<>();
		for (Map<String, String> map : recordList) {
			String[] ss = map.get("backup").split("-");

			if(ss != null && ss.length > 1) {
				set.add(Integer.parseInt(ss[1]));
			}
		}

		return Collections.isEmpty(set)
				? String.valueOf(Calendar.getInstance().get(Calendar.YEAR))
				: set.last().toString();
	}
}
